package com.yundashi.floatview;

import android.animation.TimeInterpolator;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.LayoutRes;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author : Aiden
 * @Date : 2021/01/25 13:51
 * @Description: 外部构造器
 */
public class FloatBuilder {

    private static final String mDefaultTag = "default_float_view_tag";
    private static FloatBuilder mBuilder = null;
    private static Map<String, FloatManager> mFloatWindowMap;
    public Context mApplicationContext;
    public View mView;
    public int mLayoutId;
    public int mWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
    public int mHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
    public int gravity = Gravity.TOP | Gravity.START;
    public int xOffset;
    public int yOffset;
    public int mMoveType = MoveType.slide;
    public int mSlideLeftMargin;
    public int mSlideRightMargin;
    public long mDuration = 300;
    public TimeInterpolator mInterpolator;
    public String mTag = mDefaultTag;
    public boolean mDesktopShow;
    public OnPermissionListener mPermissionListener;
    public OnViewStateListener mViewStateListener;

    public FloatBuilder(Context applicationContext) {
        mApplicationContext = applicationContext;
    }

    public static FloatManager get() {
        return get(mDefaultTag);
    }

    public static FloatManager get(@NonNull String tag) {
        return mFloatWindowMap == null ? null : mFloatWindowMap.get(tag);
    }

    @MainThread
    public static FloatBuilder with(@NonNull Context applicationContext) {
        return mBuilder = new FloatBuilder(applicationContext);
    }

    public static void destroy() {
        destroy(mDefaultTag);
    }

    public static void destroy(String tag) {
        if (mFloatWindowMap == null || !mFloatWindowMap.containsKey(tag)) {
            return;
        }
        mFloatWindowMap.get(tag).dismiss();
        mFloatWindowMap.remove(tag);
    }

    public FloatBuilder setView(@NonNull View view) {
        mView = view;
        return mBuilder;
    }

    public FloatBuilder setView(@LayoutRes int layoutId) {
        mLayoutId = layoutId;
        return mBuilder;
    }

    public FloatBuilder setWidth(int width) {
        mWidth = width;
        return mBuilder;
    }

    public FloatBuilder setHeight(int height) {
        mHeight = height;
        return mBuilder;
    }

    public FloatBuilder setWidth(@Screen.screenType int screenType, float ratio) {
        mWidth = (int) ((screenType == Screen.width ?
                Util.getScreenWidth(mApplicationContext) :
                Util.getScreenHeight(mApplicationContext)) * ratio);
        return mBuilder;
    }

    public FloatBuilder setHeight(@Screen.screenType int screenType, float ratio) {
        mHeight = (int) ((screenType == Screen.width ?
                Util.getScreenWidth(mApplicationContext) :
                Util.getScreenHeight(mApplicationContext)) * ratio);
        return mBuilder;
    }

    public FloatBuilder setX(int x) {
        xOffset = x;
        return mBuilder;
    }

    public FloatBuilder setY(int y) {
        yOffset = y;
        return mBuilder;
    }

    public FloatBuilder setX(@Screen.screenType int screenType, float ratio) {
        xOffset = (int) ((screenType == Screen.width ?
                Util.getScreenWidth(mApplicationContext) :
                Util.getScreenHeight(mApplicationContext)) * ratio);
        return mBuilder;
    }

    public FloatBuilder setY(@Screen.screenType int screenType, float ratio) {
        yOffset = (int) ((screenType == Screen.width ?
                Util.getScreenWidth(mApplicationContext) :
                Util.getScreenHeight(mApplicationContext)) * ratio);
        return mBuilder;
    }


    public FloatBuilder setMoveType(@MoveType.MOVE_TYPE int moveType) {
        return setMoveType(moveType, 0, 0);
    }


    /**
     * 设置带边距的贴边动画，只有 moveType 为 MoveType.slide，设置边距才有意义，这个方法不标准，后面调整
     *
     * @param moveType         贴边动画 MoveType.slide
     * @param slideLeftMargin  贴边动画左边距，默认为 0
     * @param slideRightMargin 贴边动画右边距，默认为 0
     */
    public FloatBuilder setMoveType(@MoveType.MOVE_TYPE int moveType, int slideLeftMargin, int slideRightMargin) {
        mMoveType = moveType;
        mSlideLeftMargin = slideLeftMargin;
        mSlideRightMargin = slideRightMargin;
        return mBuilder;
    }

    public FloatBuilder setMoveStyle(long duration, @Nullable TimeInterpolator interpolator) {
        mDuration = duration;
        mInterpolator = interpolator;
        return mBuilder;
    }

    public FloatBuilder setTag(@NonNull String tag) {
        mTag = tag;
        return mBuilder;
    }

    public FloatBuilder setDesktopShow(boolean show) {
        mDesktopShow = show;
        return mBuilder;
    }

    public FloatBuilder setOnPermissionListener(OnPermissionListener listener) {
        mPermissionListener = listener;
        return mBuilder;
    }

    public FloatBuilder setOnViewStateListener(OnViewStateListener listener) {
        mViewStateListener = listener;
        return mBuilder;
    }

    public void build() {
        if (mFloatWindowMap == null) {
            mFloatWindowMap = new HashMap<>();
        }
        if (mFloatWindowMap.containsKey(mTag)) {
            throw new IllegalArgumentException("FloatWindow of this tag has been added, Please set a new tag for the new FloatWindow");
        }
        if (mView == null && mLayoutId == 0) {
            throw new IllegalArgumentException("View has not been set!");
        }
        if (mView == null) {
            mView = Util.inflate(mApplicationContext, mLayoutId);
        }
        FloatManager floatWindowImpl = new FloatManager(this);
        mFloatWindowMap.put(mTag, floatWindowImpl);
    }
}
